﻿using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Logging;
using NLog.Extensions.Logging;
using System;
using System.IO;
using System.Linq;

namespace Core.Framework
{

    /// <summary>
    /// 服务供应商
    /// </summary>
    public static class ProviderOfServices
    {

        static ProviderOfServices()
        {
            ServiceCollection.AddNodeServices(option =>
            {
                option.InvocationTimeoutMilliseconds = 3000;
                option.NodeInstanceOutputLogger = new CustomLogger("NodeServices");
            });

            if (File.Exists("Nlog.config"))
            {
                ServiceCollection.AddLogging(builder =>
                {
                    builder.SetMinimumLevel(LogLevel.Trace);
                    builder.AddNLog(new NLogProviderOptions
                    {
                        CaptureMessageTemplates = true,
                        CaptureMessageProperties = true
                    });
                });

                //var logger = LogManager.GetLogger("*");
                //for (int i = 0; i < 5000; i++)
                //{ 
                //    logger.Warn("123");
                //    logger.Trace("123");
                //    logger.Info("这个信息");
                //    logger.Debug("这个调试");
                //    logger.Error("这个是错误");
                //}

                //ILogger<Program> logger = ProviderOfServices.GetService<ILogger<Program>>();

                //for (int i = 0; i < 500; i++)
                //{
                //    logger.LogWarning("123");
                //    logger.LogTrace("123");
                //    logger.LogInformation("这个信息");
                //    logger.LogDebug("这个调试");
                //    logger.LogError("这个是错误");
                //}
            }
        }

        public static ILoggingBuilder AddNLogging(this ILoggingBuilder logging, LogLevel level)
        {
            if (File.Exists("Nlog.config"))
            {
                logging.SetMinimumLevel(level);
                logging.AddNLog(new NLogProviderOptions
                {
                    CaptureMessageTemplates = true,
                    CaptureMessageProperties = true
                });

                return logging;
            }

            throw new Exception("not find at files is Nlog.config");

        }

        #region Parameter

        /// <summary>
        /// 服务盒子
        /// </summary>
        static IServiceCollection ServiceCollection { get; } = new ServiceCollection();

        /// <summary>
        /// 服务容器
        /// </summary>
        static IServiceProvider _Provider { get; set; }

        /// <summary>
        /// 局部锁
        /// </summary>
        static object ProviderLock { get; set; } = new object();

        /// <summary>
        /// 获取服务
        /// </summary>
        private static IServiceProvider _serviceProvider
        {
            get
            {
                if (_Provider == null)
                {
                    lock (ProviderLock)
                    {
                        if (_Provider == null)
                        {
                            _Provider = ServiceCollection
                                .BuildServiceProvider();
                        }
                    }

                }

                return _Provider;
            }
            set
            {
                _Provider = value;
            }
        }

        #endregion



        /// <summary>
        /// 初始化服务注册
        /// </summary>
        public static void DIRegister(IServiceCollection services)
        {
            var types = AppDomain.CurrentDomain.GetAssemblies()
                .SelectMany(a => a.GetTypes().Where(t => t.GetInterfaces().Contains(typeof(IDIRegister))))
                .ToArray();

            foreach (var aHandler in types)
            {
                var iRegister = (IDIRegister)Activator.CreateInstance(aHandler);

                iRegister.Execute(ServiceCollection);

                if (services != null)
                {
                    iRegister.Execute(services);
                }
            }
        }

        /// <summary>
        /// 获取服务
        /// </summary>
        /// <typeparam name="T"></typeparam>
        /// <param name="model"></param>
        /// <returns></returns>
        public static T GetService<T>() where T : class
        {
            try
            {
                var provider = _serviceProvider.GetService<T>();
                return provider;
            }
            catch (Exception ex)
            {

                throw ex;
            }
        }

        public static object GetService(Type type)
        {
            var provider = _serviceProvider.GetService(type);

            return provider;
        }

        /// <summary>
        /// 添加服务
        /// </summary>
        /// <typeparam name="T"></typeparam>
        /// <param name="model"></param>
        /// <returns></returns>
        public static void RegService(Action<IServiceCollection> action)
        {
            if (action != null)
            {
                action.Invoke(ServiceCollection);
                _Provider = null;
            }
        }

        public static IServiceCollection GetServiceCollection()
        {
            return ServiceCollection;
        }

    }
}
